/**
 * Created by Administrator on 2016/12/2.
 */
BizQQWPA.define("util.domain", function () {
    var domain = {}, dm = document.domain;
    try {
        domain.url = location.href
    } catch (e) {
        domain.url = ""
    }
    domain.topDomain = function () {
        var reg1 = /\.(?:(?:edu|gov|com|org|net)\.cn|co\.nz)$/, reg2 = /^[12]?\d?\d\.[12]?\d?\d\.[12]?\d?\d\.[12]?\d?\d$/, slicePos = reg1.test(dm) ? -3 : reg2.test(dm) ? 0 : -2;
        return dm.split(".").slice(slicePos).join(".")
    }();
    domain.domain = function () {
        var reg = /(?::[\/]{2}|:[\\]{3})([a-zA-Z0-9_\.]+)/;
        try {
            var ret = reg.exec(domain.url);
            return ret ? ret[1] || dm : dm
        } catch (e) {
            return dm
        }
    }();
    return domain
});
BizQQWPA.define("wpa.wpaMgr", "globalSettings,lang.each,util.proxy,util.cookie,util.titleFlash,util.report,util.serialize,util.domain,wpa.WPA", function (require) {
    var globalSettings = require("globalSettings"), each = require("each"), proxy = require("proxy"), titleFlash = require("titleFlash"), report = require("report"), serialize = require("serialize"), domain = require("domain"), cookie = require("cookie"), WPA = require("WPA");
    var REPORT_POSSIBILITY = 40;
    var getTencentSig = function () {
        return Math.round((Math.random() || .5) * 2147483647) * +new Date % 1e10
    }, TENCENT_SIG_NAME = "tencentSig", GAP = 1e3 * 60 * 60 * 24 * 365 * 100;
    var passRandom = function (poss) {
        var r = poss || 10;
        if (Math.random() * 100 <= r) {
            return true
        }
        return false
    };
    var reportWpa = function (url, opts) {
        if (passRandom(REPORT_POSSIBILITY)) {
            report(url + "?" + serialize(opts))
        }
    };
    var displayReport = function (params) {
        var url = "http://prom.b.qq.com/wpadisplay/r.gif?", optsArr = ["wty", "type", "nameAccount", "kfuin", "ws", "aty", "a", "title", "wording", "wording2"], reportOpts = {version: globalSettings.version};
        each(optsArr, function () {
            reportOpts[this] = typeof params[this] === "undefined" ? "" : params[this]
        });
        setTimeout(function () {
            try {
                var tencentSig = cookie.get(TENCENT_SIG_NAME);
                if (tencentSig) {
                    reportOpts[TENCENT_SIG_NAME] = tencentSig
                } else {
                    var t = getTencentSig();
                    reportOpts[TENCENT_SIG_NAME] = t;
                    cookie.set(TENCENT_SIG_NAME, t, null, null, GAP)
                }
                var _mqq = window.mqq;
                if (_mqq) {
                    _mqq.device.getDeviceInfo(function (param) {
                        if (_mqq.core.android) {
                            reportOpts.isAndroid = 1;
                            reportOpts.macAddr = param.macAddress;
                            reportOpts.imsi = param.imsi
                        } else {
                            reportOpts.isAndroid = 0;
                            reportOpts.idfa = param.idfa
                        }
                        report(url + serialize(reportOpts))
                    })
                } else {
                    report(url + serialize(reportOpts))
                }
            } catch (e) {
                if (console && console.log) {
                    console.log(e)
                }
            }
        }, 1e3)
    };
    return {
        newWPA: function (params) {
            var nameAccount = params.nameAccount;
            if (!nameAccount) {
                return
            }
            displayReport(params);
            reportWpa("http://report.b.qq.com/crmReport/accesslog", {
                FUID: cookie.get("pgv_pvi"),
                FKFUin: params.kfuin,
                FNa: params.nameAccount,
                FRurl: window.document.referrer
            });
            return new WPA(params)
        }, invite: function (params, di) {
            var mgr = this, defaultInvite = function () {
                titleFlash.on("【您有新信息】");
                params.insert = function (node) {
                    var body = document.getElementsByTagName("body")[0];
                    body.insertBefore(node, body.firstChild)
                };
                mgr.newWPA(params)
            };
            if (!di) {
                defaultInvite();
                return
            }
            try {
                var chat = proxy({params: params}, WPA.prototype.launchChat);
                window[di] && window[di](chat, params["msg"])
            } catch (e) {
                defaultInvite()
            }
        }
    }
});
BizQQWPA.define("wpa.visitor", "lang.browser,util.log,util.speedReport,util.getJSONP,util.domain,util.pubSub,wpa.filter,wpa.ta,wpa.invite,wpa.wpaMgr,wpa.ta,wpa.kfuin", function (require) {
    var invite = require("invite"), domain = require("domain"), filter = require("filter"), getJSONP = require("getJSONP"), pubSub = require("pubSub"), log = require("log"), speedReport = require("speedReport"), ta = require("ta"), kfuinCahe = require("kfuin"), browser = require("browser");
    var CRM_BLOCK_ON_SERVERSIDE = 1;
    var GET_CONFIG_URL = "http://visitor.crm2.qq.com/cgi/visitorcgi/ajax/wpa_first_heart_beat.php";
    return function (config) {
        var nameAccount = config.nameAccount;
        if (!nameAccount || nameAccount === "undefined") {
            return
        }
        if (invite.isLoaded(nameAccount) || !filter.TA) {
            return
        }
        var uid, cfg, launch = function (uid, cfg) {
            if (!uid || !cfg) {
                return
            }
            if (cfg.block === CRM_BLOCK_ON_SERVERSIDE) {
                return
            }
            if (browser && browser.ua) {
                var spiderReg = /spider|bot|^\s*$/;
                if (spiderReg.test(browser.ua)) {
                    return
                }
            }
            if (filter.CRM) {
                cfg.di = config.di;
                cfg.kfuin = config.kfuin;
                log(nameAccount + " try launch slave");
                invite.load(nameAccount, uid, cfg)
            }
        };
        pubSub.one("TA.loaded", function (data) {
            uid = data;
            launch(uid, cfg)
        });
        pubSub.one("Invite.first", function (data) {
            cfg = data;
            launch(uid, cfg)
        });
        ta(nameAccount, domain.topDomain, function (uid) {
            pubSub.pub("TA.loaded", uid)
        });
        var opts = {
            nameAccount: nameAccount,
            dm: domain.topDomain,
            title: document.title,
            url: location.href.split("://")[1].split("?")[0]
        };
        getJSONP(GET_CONFIG_URL, opts, function (cfg) {
            pubSub.pub("Invite.first", cfg)
        });
        config.kfuin && kfuinCahe.set(nameAccount, config.kfuin)
    }
});
BizQQWPA.define("wpa.kfuin", "util.getJSONP", function (require) {
    var getJSONP = require("getJSONP");
    var GET_KFUIN_URL = "http://wpl.b.qq.com/cgi/conv.php";
    var kfuins = {};
    return {
        get: function (nameAccount, callback) {
            callback = callback || function () {
                };
            if (!nameAccount || kfuins[nameAccount]) {
                callback(kfuins[nameAccount]);
                return
            }
            var opts = {num: nameAccount};
            getJSONP(GET_KFUIN_URL, opts, function (rs) {
                if (!rs || rs.r !== 0) {
                    callback();
                    return
                }
                var kfuin = kfuins[nameAccount] = rs.data.kfuin;
                callback(kfuin)
            })
        }, set: function (nameAccount, kfuin) {
            kfuins[nameAccount] = kfuin
        }
    }
});
BizQQWPA.define("util.proxy", function () {
    return function (ns, fn) {
        return function () {
            return fn.apply(ns, arguments)
        }
    }
});
BizQQWPA.define("util.titleFlash", "util.taskMgr", function (require) {
    var TITLE_FLASH_GAP = 120;
    var taskMgr = require("taskMgr");
    var doc = document, title = doc.title, task = taskMgr.newTask(function () {
        var t = doc.title;
        doc.title = t.substr(1, t.length) + t.substr(0, 1)
    }, TITLE_FLASH_GAP);
    return titleFlash = {
        on: function (msg) {
            doc.title = msg + ("" + doc.title);
            task.run()
        }, off: function () {
            task.pause();
            doc.title = title
        }
    }
});
BizQQWPA.define("util.cookie", function () {
    var doc = document;
    return {
        set: function (name, value, domain, path, expires) {
            if (expires) {
                expires = new Date(+new Date + expires)
            }
            var tempcookie = name + "=" + escape(value) + (expires ? "; expires=" + expires.toGMTString() : "") + (path ? "; path=" + path : "") + (domain ? "; domain=" + domain : "");
            if (tempcookie.length < 4096) {
                doc.cookie = tempcookie
            }
        }, get: function (name) {
            var carr = doc.cookie.match(new RegExp("(^| )" + name + "=([^;]*)(;|$)"));
            if (carr != null) {
                return unescape(carr[2])
            }
            return null
        }, del: function (name, domain, path) {
            if (this.get(name)) {
                doc.cookie = name + "=" + (path ? "; path=" + path : "") + (domain ? "; domain=" + domain : "") + ";expires=Thu, 01-Jan-1970 00:00:01 GMT"
            }
        }, find: function (pattern) {
            return doc.cookie.match(pattern).split(",")
        }
    }
});
BizQQWPA.define("wpa.WPA", "globalSettings,lang.browser,util.cookie,util.localStorage,lang.typeEnhance,util.serialize,util.proxy,util.pad,util.Bits,util.getScript,util.getJSONP,util.domain,util.events,util.onLoad,util.offset,util.report,util.log,util.speedReport,wpa.SelectPanel,util.onIframeLoaded,util.GUID,wpa.getQQVersion,wpa.ViewHelper,wpa.views,wpa.ta,wpa.kfuin,wpa.sid", function (require) {
    function fetch(uri, id, cb) {
        var node = document.createElement("script");
        node.charset = "utf-8", node.async = !0, node.src = uri, node.id = id || "";
        var currentlyAddingScript = node;
        node.onreadystatechange = node.onload = function () {
            /loaded|complete|undefined/.test(node.readyState) && "function" == typeof cb && (cb(), node.onreadystatechange = node.onload = null)
        }, baseElement ? head.insertBefore(node, baseElement) : head.appendChild(node), currentlyAddingScript = null
    }

    var visitorId, globalSettings = require("globalSettings"), proxy = require("proxy"), typeEnhance = require("typeEnhance"), getJSONP = (require("pad"), require("Bits"), require("getScript"), require("getJSONP")), domain = require("domain"), events = require("events"), onLoad = require("onLoad"), serialize = require("serialize"), browser = require("browser"), offset = require("offset"), report = require("report"), speedReport = (require("log"), require("speedReport")), GUID = require("GUID"), SelectPanel = require("SelectPanel"), onIframeLoaded = require("onIframeLoaded"), getQQVersion = require("getQQVersion"), ViewHelper = require("ViewHelper"), views = require("views"), ta = require("ta"), kfuinCache = require("kfuin"), cookie = require("cookie"), localStorage = require("util.localStorage"), sidCache = require("sid"), global = window, isDaAdded = "isDaAdded", isFetchingDa = "isFetchingDa", daList = [], TENCENT_SIG = "tencentSig", WPA_TYPE_NORMAL = "1", WPA_TYPE_CUSTOM = "3", CHAT_TYPE_AIO = 1, CHAT_TYPE_ANONYMOUS = 2, SPEED_REPORT_DISPLAY = .1, REPORT_POSSIBILITY = 40;
    try {
        var mqqSrc = "//open.mobile.qq.com/sdk/qqapi.js?_bid=152", head = document.head || document.getElementsByTagName("head")[0] || document.documentElement, baseElement = head.getElementsByTagName("base")[0];
        window.mqq || !browser.isIOS && !browser.isAndroid || fetch(mqqSrc, "_mqq")
    } catch (e) {
        console && console.log
    }
    var passRandom = function (poss) {
        var r = poss || 10;
        return 100 * Math.random() <= r ? !0 : !1
    }, randomId = function () {
        return Math.round(2147483647 * (Math.random() || .5)) * +new Date % 1e10
    }, reportWpa = function (url, opts) {
        passRandom(REPORT_POSSIBILITY) && report(url + "?" + serialize(opts))
    }, _log = function (msg) {
        console && console.log
    }, qidianDAReport = function () {
        try {
            var GLOBAL = window, HOOK_NAME = "__qq_qidian_da", EXPORT_NAME = GLOBAL[HOOK_NAME] || "qidianDA";
            if (!EXPORT_NAME)return;
            var qidianDA = GLOBAL[EXPORT_NAME], nameAccount = daList.shift();
            if (!nameAccount)return;
            qidianDA("create", String(nameAccount), {
                cid: String(visitorId),
                src: 12,
                pgv_pvi: cookie.get("pgv_pvi") || ""
            }), qidianDA("set", "t1", new Date)
        } catch (e) {
            _log("[WPA][qidianDAReport]:error occured"), _log(e)
        }
    }, addDaScript = function (nameAccount) {
        daList.push(nameAccount), top[isFetchingDa] ? top[isDaAdded] && qidianDAReport() : (top[isFetchingDa] = !0, fetch("//bqq.gtimg.com/da/i.js", "_da", function () {
            top[isDaAdded] = !0, qidianDAReport()
        }))
    }, WPA = function (params) {
        this.params = params, this.insert = params.insert, this.wty = params.wty;
        var self = this, nameAccount = this.nameAccount = params.nameAccount;
        this.kfuin = params.kfuin;
        if (localStorage.getItem(TENCENT_SIG)) visitorId = params.guid = localStorage.getItem(TENCENT_SIG); else {
            var guid = randomId();
            visitorId = params.guid = guid, localStorage.setItem(TENCENT_SIG, guid)
        }
        switch (this.wty) {
            case WPA_TYPE_NORMAL:
                this.render();
                break;
            case WPA_TYPE_CUSTOM:
                this.custom()
        }
        !this.kfuin && kfuinCache.get(nameAccount, function (data) {
            data && (self.kfuin = data)
        }), !this.sid && sidCache.get(nameAccount, function (data) {
            data && (self.sid = data)
        }), setTimeout(function () {
            addDaScript(nameAccount)
        }, 10), report("http://prom.b.qq.com/se/r.gif?na=" + nameAccount + "&ref=" + encodeURIComponent(document.referrer))
    };
    return WPA.prototype = {
        render: function () {
            var width, height, typeStr, params = this.params, type = parseInt(params.type), isFloat = !1;
            switch (type) {
                case 1:
                    typeStr = "a01", width = 92, height = 22;
                    break;
                case 2:
                    typeStr = "a02", width = 77, height = 22;
                    break;
                case 10:
                    typeStr = "b01", width = 93, height = 151, isFloat = !0;
                    break;
                case 11:
                    typeStr = "b02", width = 327, height = 172, isFloat = !0;
                    break;
                case 12:
                    typeStr = "b03", width = 121, height = 277, isFloat = !0;
                    break;
                case 20:
                    typeStr = "i01", width = 327, height = 172, isFloat = !0;
                    break;
                case 30:
                    typeStr = "d01", width = params.txw, height = params.txh, isFloat = !0
            }
            this.type = typeStr, this.width = width, this.height = height, this.createWPA(), (type > 9 && 14 > type || 20 === type || 30 === type) && this.initFloatWPA()
        }, createWPA: function () {
            var iframe, speedRpt = speedReport("7818", "21", "1"), wpa = this, type = this.type, width = this.width, height = this.height, view = views[type];
            try {
                iframe = document.createElement('<iframe scrolling="no" frameborder="0" width="' + width + '" height="' + height + '" allowtransparency="true" src="about:blank"></iframe>')
            } catch (e) {
                iframe = document.createElement("iframe"), iframe.width = width, iframe.height = height, iframe.setAttribute("scrolling", "no"), iframe.setAttribute("frameborder", 0), iframe.setAttribute("allowtransparency", !0), iframe.setAttribute("src", "about:blank")
            }
            if (this.node = iframe, this.insert(iframe), browser.msie)try {
                iframe.contentWindow.document
            } catch (e) {
                iframe.src = "javascript:void((function(){document.open();document.domain='" + document.domain + "';document.close()})())"
            }
            var loaded = function () {
                var iWin = iframe.contentWindow, iDoc = iframe.contentDocument || iWin.document;
                iDoc.open(), iDoc.write(['<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">', '<html xmlns="http://www.w3.org/1999/xhtml">', "<head>", '<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />', browser.msie && "about:blank" !== iframe.src ? "<script>document.domain='" + document.domain + "';</script>" : "", "</head>", "<body>", view.templ, "</body>", "</html>"].join("")), iDoc.close();
                var helper = new ViewHelper(iDoc, wpa);
                view.init(iDoc, helper);
                var point = 1;
                speedRpt.addPoint(point).send(SPEED_REPORT_DISPLAY)
            };
            onIframeLoaded(iframe, loaded)
        }, initFloatWPA: function () {
            function initIframeLoad() {
                var isty = node.style, isIE = browser.msie, ver = parseInt(browser.version, 10), isQuirk = "BackCompat" === doc.compatMode;
                if (isty.position = 0 == parseInt(params.fsty, 10) ? "fixed" : "absolute", 0 == parseInt(params.fposX) ? (isty.left = "8px", isty.right = "auto", isty.marginLeft = 0) : 1 == parseInt(params.fposX) ? (isty.left = "50%", isty.right = "auto", isty.marginLeft = "-" + parseInt(width / 2) + "px") : (isty.left = "auto", isty.right = "8px", isty.marginLeft = 0), 0 == parseInt(params.fposY) ? (isty.top = "8px", isty.bottom = "auto", isty.marginTop = 0) : 1 == parseInt(params.fposY) ? (isty.top = "50%", isty.bottom = "auto", isty.marginTop = "-" + parseInt(height / 2) + "px") : (isty.top = "auto", isty.bottom = "8px", isty.marginTop = 0), (isIE & 7 > ver || isQuirk) && (isty.position = "absolute", 0 == parseInt(params.fsty))) {
                    isty.marginTop = 0;
                    var itop;
                    itop = 0 == parseInt(params.fposY) ? 8 : 1 == parseInt(params.fposY) ? (offset.getClientHeight(doc) - height) / 2 : offset.getClientHeight(doc) - height - 8, setInterval(function () {
                        isty.top = offset.getScrollTop(doc) + itop + "px"
                    }, 128)
                }
                isty.display = "block"
            }

            var doc = window.document, params = this.params, type = parseInt(params.type), node = this.node, width = this.width, height = this.height;
            node.style.cssText = ["display:none;", "position:absolute;", 20 === type ? "z-index:2147483647!important;" : "z-index:2147483646!important;"].join(" "), onLoad(initIframeLoad)
        }, custom: function () {
            events.addEvent(this.params.node, "click", proxy(this, this.launchChat))
        }, remove: function () {
            var node = this.node;
            node.parentNode.removeChild(node)
        }, launchChat: function (callback) {
            var wpa = this, sptReport = speedReport("7818", "21", "2"), chatType = this.params.chatType;
            return reportWpa("http://report.b.qq.com/crmReport/clicklog", {
                FUID: cookie.get("pgv_pvi"),
                FKFUin: wpa.params.kfuin,
                FNa: wpa.params.nameAccount,
                FRurl: global.document.referrer
            }), browser.isIOS || browser.isAndroid ? void this.launchMobileChat() : chatType == CHAT_TYPE_ANONYMOUS ? void wpa.launchAnonymousChat(callback) : chatType == CHAT_TYPE_AIO ? void wpa.launchAIOChat(callback) : (!browser.msie && wpa.launchAIOChat(callback), void getQQVersion(function (version) {
                return sptReport.addPoint(7).send(), version ? void(browser.msie && wpa.launchAIOChat(callback)) : void new SelectPanel({
                    onAIOChat: function () {
                        wpa.launchAIOChat(callback)
                    }, onAnonyChat: function () {
                        wpa.launchAnonymousChat(callback)
                    }
                })
            }))
        }, launchMobileChat: function () {
            var nameAccount = this.params.nameAccount;
            kfuinCache.get(nameAccount, function (kfuin) {
                function schema() {
                    var dm = domain.domain, type = "crm";
                    return browser.isQQ && "4.5" === browser.QQVersion && (type = "wpa"), browser.isQQ ? "mqqwpa://im/chat?chat_type=" + type + "&uin=" + kfuin + "&version=1&src_type=web&web_src=" + location.protocol + "://" + dm : browser.isAndroid && browser.chrome && parseInt(browser.version, 10) > 25 ? "intent://im/chat?chat_type=" + type + "&uin=" + kfuin + "&version=1&src_type=web&web_src=" + location.protocol + "://" + dm + "#Intent;scheme=mqqwpa;action=android.intent.action.VIEW;end" : "mqqwpa://im/chat?chat_type=" + type + "&uin=" + kfuin + "&version=1&src_type=web&web_src=" + location.protocol + "://" + dm
                }

                function launch(schema, fail) {
                    var start = +new Date;
                    location.href = schema, setTimeout(function () {
                        var gap = +new Date - start;
                        6e3 > gap && fail && fail()
                    }, 5e3)
                }

                function fallback() {
                    location.href = "http://wpd.b.qq.com/page/info.php?nameAccount=" + nameAccount
                }

                return navigator.userAgent.indexOf("MicroMessenger") > -1 && -1 === domain.domain.indexOf("qq.com") ? void(location.href = "http://wpd.b.qq.com/page/info.php?nameAccount=" + nameAccount) : void launch(schema(), fallback)
            })
        }, launchAIOChat: function () {
            var iframe = document.createElement("iframe"), body = document.getElementsByTagName("body")[0];
            return iframe.style.display = "none", body.insertBefore(iframe, body.firstChild), function (callback) {
                var params = this.params, kfuin = this.kfuin, opts = {
                    na: params.nameAccount,
                    kfuin: kfuin,
                    aty: params.aty,
                    a: params.a,
                    sid: this.sid,
                    uid: ta.uid,
                    url: domain.url,
                    title: document.title,
                    dm: domain.topDomain,
                    clkSrc: params.clkSrc || "",
                    ext: params.ext || ""
                }, guid = GUID(), sptReport = speedReport("7818", "21", "2");
                getJSONP("http://wpd.b.qq.com/cgi/get_sign.php", opts, function (rs) {
                    if (rs && 0 === rs.r && rs.data) {
                        iframe.src = rs.data.sign;
                        var isLoaded = !1, loaded = function () {
                            if (!isLoaded) {
                                isLoaded = !0;
                                var clickId = rs.data.clkID;
                                sptReport.addPoint(5).send(), report("http://promreport.crm2.qq.com/wpaclick/r.gif?ty=1&kfuin=" + kfuin + "&version=" + globalSettings.version + "&browser=" + encodeURIComponent(navigator.userAgent) + "&bfrom=1&appointType=" + params.aty + "&appoint=" + params.a + "&clkID=" + clickId + "&guid=" + guid), global.taClick && global.taClick(clickId, "clickid"), typeEnhance.isFunction(callback) && setTimeout(function () {
                                    callback(params)
                                }, 1e3)
                            }
                        };
                        if (onIframeLoaded(iframe, loaded), browser.msie) {
                            var fallback = function () {
                                setTimeout(function () {
                                    isLoaded || (/interactive/.test(iframe.readyState) ? loaded() : fallback())
                                }, 500)
                            };
                            fallback()
                        }
                    }
                }), report("http://promreport.crm2.qq.com/wpaclickorg/r.gif?kfuin=" + kfuin + "&version=" + globalSettings.version + "&browser=" + encodeURIComponent(navigator.userAgent) + "&bfrom=1&appointType=" + params.aty + "&appoint=" + params.a + "&guid=" + guid)
            }
        }(), launchAnonymousChat: function (callback) {
            var params = this.params, sptReport = speedReport("7818", "21", "2"), url = "http://wpd.b.qq.com/page/webchat.html?nameAccount=" + this.nameAccount, opener = window.open(url, "_blank", "height=516, width=598,toolbar=no,scrollbars=no,menubar=no,status=no,location=no");
            typeEnhance.isFunction(callback) && callback(params), report("http://promreport.crm2.qq.com/wpaclick/r.gif?ty=2&kfuin=" + this.kfuin + "&version=" + globalSettings.version + "&browser=" + encodeURIComponent(navigator.userAgent) + "&bfrom=1&appointType=" + params.aty + "&appoint=" + params.a), opener.onload = function () {
                sptReport.addPoint(6).send()
            }
        }
    }, WPA
});
BizQQWPA.define("util.getJSONP", "util.getScript,util.serialize", function (require) {
    var getScript = require("getScript"), serialize = require("serialize");
    var count = 0;
    return function (url, options, callback) {
        var fnName = "JSONP_CALLBACK_" + ++count + "_" + Math.round(Math.random() * 100), script;
        options.cb = fnName;
        url += url.indexOf("?") === -1 ? "?" : "&";
        url += serialize(options);
        script = getScript(url);
        window[fnName] = function (json) {
            callback(json);
            setTimeout(function () {
                window[fnName] = null;
                script.parentNode.removeChild(script)
            }, 1)
        }
    }
});
BizQQWPA.define("wpa.filter", "util.domain", function (require) {
    var TA_BLACKLIST = "", CRM_BLACKLIST = "qq.com,pengyou.com,qzoneapp.com,nipic.com,docin.com,51zxw.net,2155.com,xd.com,yto.net.cn,c-c.com,27.cn,05wan.com,alivv.cn,gogo.com,doctorjob.com.cn,emoney.cn,m4.cn,chinaktv.net,yk988.com,bangkaow.com,wsxsp.com,55tools.com,youxi518.com", CRM_WHITELIST = "b.qq.com,sales.b.qq.com,guilin.house.qq.com,ta.qq.com,hn.qq.com,nantong.house.qq.com";
    var domain = require("domain");
    return {
        TA: function () {
            var dm = domain.topDomain, IPReg = /^[12]?\d?\d\.[12]?\d?\d\.[12]?\d?\d\.[12]?\d?\d$/, LocalReg = /^localhost$/, previewPageReg = /^wpa\.b\.qq\.com/;
            return TA_BLACKLIST.indexOf(dm) === -1 && !IPReg.test(dm) && !LocalReg.test(dm) && !previewPageReg.test(domain.domain)
        }(), CRM: function () {
            try {
                var reg = new RegExp("(^|,)" + domain.domain);
                if (reg.test(CRM_WHITELIST)) {
                    return true
                }
                var dm = domain.topDomain, dmReg = new RegExp("(^|,)" + dm), IPReg = /^[12]?\d?\d\.[12]?\d?\d\.[12]?\d?\d\.[12]?\d?\d$/, LocalReg = /^localhost$/;
                return !dmReg.test(CRM_BLACKLIST) && !IPReg.test(dm) && !LocalReg.test(dm)
            } catch (e) {
            }
        }()
    }
});
BizQQWPA.define("wpa.ta", "util.getScript,util.serialize,util.cookie", function (require) {
    var URL = "http://tajs.qq.com/crmqq.php", UID_COOKIE_NAME = "pgv_pvi";
    var getScript = require("getScript"), serialize = require("serialize"), cookie = require("cookie");
    var loaded = false;
    var ta = function (nameAccount, domain, callback) {
        var isTriggered = false;
        if (ta.uid) {
            callback(ta.uid);
            isTriggered = true
        }
        if (!loaded) {
            var options = {uid: nameAccount, dm: domain}, url = URL + "?" + serialize(options, "=", "&");
            getScript(url, function () {
                loaded = true;
                if (isTriggered) {
                    return
                }
                ta.uid = cookie.get(UID_COOKIE_NAME);
                if (ta.uid) {
                    callback(ta.uid)
                } else {
                    setTimeout(arguments.callee, 30)
                }
            })
        }
    };
    ta.uid = cookie.get(UID_COOKIE_NAME) || "";
    return ta
});
BizQQWPA.define("wpa.invite", "util.log,util.getJSONP,util.proxy,util.domain,util.blockStorage,util.taskMgr,wpa.wpaMgr", function (require) {
    var MASTER_MONITOR_GAP = 2e3, INVITE_MONITOR_GAP = 1e3, MASTER_HEATBEAT_GAP = 2e3, SLAVE_HEARTBEAT_GAP = 2e3, SERVER_MONITOR_GAP_MIN = 5e3, SERVER_MONITOR_GAP_MAX = 15e3, SERVER_MONITOR_SLEEPCHECK_GAP = 36e5, SERVER_MONITOR_SLEEPING_GAP = 1e3;
    var INVITE_SIGNAL = "is", INVITE_KFEXT = "ik", INVITE_MSG = "msg", MASTER_HEARTBEATS = "mh", MASTER_ID = "mid", SLAVE_IDS = "slid";
    var INVITE_SIGNAL_UNINVITED = "0", INVITE_SIGNAL_INVITE = "1", INVITE_SIGNAL_INVITED = "2", INVITE_KFEXT_AUTO = "0", MASTER_HEARTBEATS_ERROR = "-1", DATA_SEPERATOR = "|";
    var HEARTBEAT_URL = "http://visitor.crm2.qq.com/cgi/visitorcgi/ajax/wpa_heart_beat.php", CONFIRM_AUTO_INVITE_URL = "http://visitor.crm2.qq.com/cgi/visitorcgi/ajax/auto_invite.php";
    var RESULT_SUCCESS = 0, INVITE_STATE_UNINVITED = "0", INVITE_STATE_INVITE = "1", INVITE_STATE_INVITED = "2", AUTO_INVITE_TRUE = 1;
    var WPA_TYPE_TA_INVITE_ONLY = "0", WPA_TYPE_NORMAL = "1", WPA_TYPE_LINK = "2", SESSION_VERSION_TA = "4", WPA_STYLE_TYPE_INVITE = "20", APPOINTED_TYPE_AUTO = "0", APPOINTED_TYPE_KFEXT = "1", APPOINTED_TYPE_GROUP = "2", APPOINTED_TYPE_AUTO_INVITE = "4", APPOINTED_TYPE_INVITE = "5";
    var WPA_FLOAT_TYPE_FIXED = "0", WPA_FLOAT_POSITION_Y_CENTER = "1", WPA_FLOAT_POSITION_X_CENTER = "1", IS_INVITE_WPA_FALSE = "0", IS_INVITE_WPA_TRUE = "1";
    var log = require("log"), getJSONP = require("getJSONP"), proxy = require("proxy"), domain = require("domain"), blockStorage = require("blockStorage"), taskMgr = require("taskMgr"), wpaMgr = require("wpaMgr");
    var Slave = function (nameAccount, uid, cfg) {
        this.nameAccount = nameAccount;
        this.uid = uid;
        this.config = cfg;
        this.genID();
        this.storage = blockStorage(nameAccount);
        this.monitors = {
            master: taskMgr.newTask(proxy(this, this.masterMonitor), MASTER_MONITOR_GAP).run(),
            invite: taskMgr.newTask(proxy(this, this.inviteMonitor), INVITE_MONITOR_GAP).run()
        };
        this.heartBeat = taskMgr.newTask(proxy(this, this.heartBeatProcess), SLAVE_HEARTBEAT_GAP).run();
        this.setActive();
        window.onfocus = proxy(this, this.setActive);
        log("slave " + this.id + " launched!")
    };
    Slave.prototype = {
        genID: function () {
            this.id = "slid_" + +new Date % 1e3 + "_" + Math.round(Math.random() * 100)
        }, masterMonitor: function () {
            if (masters[this.nameAccount]) {
                return
            }
            log("monitoring mater state");
            var lastMasterHeartbeat = this.storage.get(MASTER_HEARTBEATS) || 0, gap = +new Date - parseInt(lastMasterHeartbeat);
            log("gap of master is " + gap);
            if (gap > 3 * MASTER_HEATBEAT_GAP) {
                this.recoverMaster()
            }
        }, recoverMaster: function () {
            masters[this.nameAccount] = new Master(this.nameAccount, this.uid, this.config);
            log("recover master by slave " + this.id)
        }, inviteMonitor: function () {
            if (this.isInvited()) {
                this.kill()
            } else if (this.isInviting()) {
                if (this.isActive()) {
                    this.invite()
                }
            }
            log("slave " + this.id + " monitoring invite state")
        }, kill: function () {
            this.monitors.invite.drop();
            this.heartBeat.drop();
            var storage = this.storage, keys = [this.id];
            for (var i = 0, key; key = keys[i++];) {
                storage.del(key)
            }
            log("slave " + this.id + " killed")
        }, invite: function () {
            var kfext = this.storage.get(INVITE_KFEXT);
            var params = {
                wty: WPA_TYPE_NORMAL,
                nameAccount: this.nameAccount,
                kfuin: this.config.kfuin,
                type: WPA_STYLE_TYPE_INVITE,
                aty: kfext ? kfext === INVITE_KFEXT_AUTO ? APPOINTED_TYPE_AUTO_INVITE : APPOINTED_TYPE_INVITE : APPOINTED_TYPE_AUTO_INVITE,
                a: kfext || "",
                iv: IS_INVITE_WPA_TRUE,
                fsty: WPA_FLOAT_TYPE_FIXED,
                fposX: WPA_FLOAT_POSITION_X_CENTER,
                fposY: WPA_FLOAT_POSITION_Y_CENTER,
                sv: SESSION_VERSION_TA,
                uid: this.uid,
                dm: domain.topDomain,
                msg: this.storage.get(INVITE_MSG)
            };
            wpaMgr.invite(params, this.config.di);
            this.storage.set(INVITE_SIGNAL, INVITE_SIGNAL_INVITED);
            log("invited by slave " + this.id)
        }, heartBeatProcess: function () {
            var storage = this.storage, ids = storage.get(SLAVE_IDS);
            if (!ids) {
                storage.set(SLAVE_IDS, this.id + "|")
            } else if (ids.indexOf(this.id + "|") === -1) {
                storage.set(SLAVE_IDS, this.id + "|" + ids)
            }
            storage.set(this.id, +new Date)
        }, setActive: function () {
            var storage = this.storage, ids = storage.get(SLAVE_IDS) || "", sign = this.id + DATA_SEPERATOR;
            if (ids.indexOf(this.id) > -1) {
                ids = ids.replace(sign, "")
            }
            ids += sign;
            storage.set(SLAVE_IDS, ids)
        }, isActive: function () {
            var slaves = this.storage.get(SLAVE_IDS);
            if (!slaves) {
                return false
            }
            return slaves.substr(0, slaves.length - 1).split(DATA_SEPERATOR).pop() === this.id
        }, isInvited: function () {
            return this.storage.get(INVITE_SIGNAL) === INVITE_SIGNAL_INVITED
        }, isInviting: function () {
            return this.storage.get(INVITE_SIGNAL) === INVITE_SIGNAL_INVITE
        }
    };
    var masters = {};
    var Master = function (nameAccount, uid, cfg) {
        this.nameAccount = nameAccount;
        this.uid = uid;
        this.config = cfg;
        this.storage = blockStorage(nameAccount);
        this.genID();
        this.sleep = false;
        this.heartBeatURl = cfg.hbDomain || HEARTBEAT_URL;
        this.storage.set(MASTER_ID, this.id);
        this.heartBeatProcess();
        this.heartBeat = taskMgr.newTask(proxy(this, this.heartBeatProcess), MASTER_HEATBEAT_GAP).run();
        this.initWithConfig();
        log("master launched!")
    };
    Master.prototype = {
        genID: function () {
            this.id = +new Date % 1e3 + "_" + Math.round(Math.random() * 100)
        }, setInviteState: function (signal, kfext, msg) {
            if (signal === INVITE_SIGNAL_INVITE) {
                this.storage.set(INVITE_KFEXT, kfext);
                this.storage.set(INVITE_MSG, msg)
            }
            this.storage.set(INVITE_SIGNAL, signal)
        }, isInvited: function () {
            var invited = this.storage.get(INVITE_SIGNAL) === INVITE_SIGNAL_INVITED;
            if (invited) {
                this.recycle();
                this.isInvited = function () {
                    return true
                }
            }
            return invited
        }, initWithConfig: function () {
            var cfg = this.config;
            if (cfg.r !== RESULT_SUCCESS) {
                this.storage.set(MASTER_HEARTBEATS, MASTER_HEARTBEATS_ERROR);
                return
            }
            if (cfg.isAuto === AUTO_INVITE_TRUE) {
                this.storage.set(INVITE_MSG, cfg.autoMsg);
                this.autoInviteTimer = setTimeout(proxy(this, function () {
                    this.autoInvite()
                }), cfg.autoTime * 1e3)
            }
            this.monitors = {
                slave: taskMgr.newTask(proxy(this, this.slaveMonitor), SLAVE_HEARTBEAT_GAP).run(),
                server: taskMgr.newTask(proxy(this, this.serverMonitor), SERVER_MONITOR_GAP_MIN).run(),
                sleep: taskMgr.newTask(proxy(this, this.sleepMonitor), SERVER_MONITOR_SLEEPCHECK_GAP).run()
            };
            log("master inited with config")
        }, autoInvite: function () {
            if (this.isInvited()) {
                return
            }
            var opt = {nameAccount: this.nameAccount, uid: this.uid};
            var serverMonitor = this.monitors.server;
            serverMonitor.pause();
            getJSONP(CONFIRM_AUTO_INVITE_URL, opt, proxy(this, function (rs) {
                if (rs.r !== RESULT_SUCCESS) {
                    serverMonitor.run();
                    return
                }
                if (!this.isInvited()) {
                    this.setInviteState(INVITE_SIGNAL_INVITE, INVITE_KFEXT_AUTO, this.storage.get(INVITE_MSG));
                    taskMgr.once(function () {
                        serverMonitor.run()
                    }, 5e3).run()
                }
            }))
        }, ajustServerMonitorGap: function (time) {
            this.monitors.server.setGap(Math.min(Math.max(SERVER_MONITOR_GAP_MIN, time), SERVER_MONITOR_GAP_MAX))
        }, serverMonitor: function () {
            var inviteSignal = this.storage.get(INVITE_SIGNAL);
            if (this.sleep) {
                return
            }
            var opt = {nameAccount: this.nameAccount, uid: this.uid};
            if (inviteSignal === INVITE_SIGNAL_INVITE) {
                opt["inviteState"] = INVITE_STATE_INVITE
            }
            if (inviteSignal === INVITE_SIGNAL_INVITED) {
                opt["inviteState"] = INVITE_STATE_INVITED
            }
            getJSONP(this.heartBeatURl, opt, proxy(this, function (rs) {
                if (rs.r !== RESULT_SUCCESS) {
                    return
                }
                if (rs.gap) {
                    this.ajustServerMonitorGap(rs.gap * 1e3)
                }
                if (rs.inviteState === INVITE_STATE_UNINVITED) {
                    return
                }
                if (rs.inviteState === INVITE_STATE_INVITE) {
                    this.setInviteState(INVITE_SIGNAL_INVITE, rs.kfext, rs.inviteMsg);
                    return
                }
                if (rs.inviteState === INVITE_STATE_INVITED) {
                    this.setInviteState(INVITE_SIGNAL_INVITED)
                }
            }))
        }, slaveMonitor: function () {
            if (this.isInvited()) {
                this.monitors.slave.drop()
            }
            var storage = this.storage, slaves = storage.get(SLAVE_IDS);
            if (!slaves) {
                return
            }
            slaves = slaves.split(DATA_SEPERATOR);
            var aliveSlaves = "", time = +new Date, lastSlaveHeartbeat, slave, gap;
            for (var i = 0; slave = slaves[i++];) {
                log("monitoring slave " + slave + " state");
                lastSlaveHeartbeat = storage.get(slave) || 0;
                gap = time - parseInt(lastSlaveHeartbeat);
                log("gap of slave " + slave + " is " + gap);
                if (gap > 3 * SLAVE_HEARTBEAT_GAP) {
                    storage.del(slave);
                    log("clear slave " + slave + " in storage")
                } else {
                    aliveSlaves += slave + DATA_SEPERATOR
                }
            }
            storage.set(SLAVE_IDS, aliveSlaves)
        }, sleepMonitor: function () {
            var slaves = this.storage.get(SLAVE_IDS) || "", activeSlave = slaves.substr(0, slaves.length - 1).split(DATA_SEPERATOR).pop();
            if (this.sleep) {
                if (this.activeSlave !== activeSlave) {
                    this.activeSlave = activeSlave;
                    this.sleep = false;
                    this.monitors.sleep.setGap(SERVER_MONITOR_SLEEPCHECK_GAP)
                }
            } else {
                if (this.activeSlave === activeSlave) {
                    this.sleep = true;
                    this.monitors.sleep.setGap(SERVER_MONITOR_SLEEPING_GAP)
                } else {
                    this.activeSlave = activeSlave
                }
            }
        }, kill: function () {
            masters[this.nameAccount] = undefined;
            if (this.monitors) {
                this.monitors.server.drop();
                this.monitors.slave.drop();
                this.heartBeat.drop();
                clearTimeout(this.autoInviteTimer)
            }
            log("master killed")
        }, recycle: function () {
            var storage = this.storage, keys = [INVITE_KFEXT, INVITE_MSG];
            for (var i = 0, key; key = keys[i++];) {
                storage.del(key)
            }
            log("storage recycled")
        }, heartBeatProcess: function () {
            var storage = this.storage;
            if (storage.get(MASTER_ID) !== this.id) {
                this.kill();
                return false
            }
            this.storage.set(MASTER_HEARTBEATS, +new Date)
        }
    };
    var slaves = {};
    return {
        load: function (nameAccount, uid, cfg) {
            if (this.isLoaded(nameAccount)) {
                log(nameAccount + " slave already running");
                return
            }
            var slave = new Slave(nameAccount, uid, cfg);
            slaves[nameAccount] ? slaves[nameAccount].push(slave) : slaves[nameAccount] = [slave]
        }, isLoaded: function (nameAccount) {
            return typeof slaves[nameAccount] !== "undefined"
        }
    }
});
BizQQWPA.define("util.taskMgr", "util.proxy", function (require) {
    var TASK_RUN = "run", TASK_PAUSE = "pause", TASK_DROP = "drop", LOOP_TIME = 50;
    var proxy = require("proxy");
    var TM = function () {
        this.circle = [];
        this.pos = 0;
        setInterval(proxy(this, this.loop), 16)
    };
    TM.prototype = {
        newTask: function (fn, gap) {
            var t = new Task(fn, gap);
            this.circle.push(t);
            return t
        }, once: function (fn, gap) {
            return this.newTask(function () {
                fn.apply(this);
                this.drop()
            }, gap)
        }, loop: function () {
            var c = this.circle, pos = this.pos, count = c.length, start = +new Date, loopTime = LOOP_TIME, t = c[pos];
            while (count > 0 && +new Date - start < loopTime) {
                if (t.isRunning()) {
                    t.execute()
                } else if (t.isDropped()) {
                    c.splice(pos, 1);
                    pos--
                }
                pos = (pos + 1) % c.length;
                t = c[pos];
                count--
            }
            this.pos = pos
        }
    };
    var Task = function (fn, gap) {
        this.fn = fn;
        this.gap = gap;
        this.status = TASK_PAUSE;
        this.lastExecTime = +new Date
    };
    Task.prototype = {
        run: function () {
            this.status = TASK_RUN;
            return this
        }, pause: function () {
            this.status = TASK_PAUSE;
            return this
        }, drop: function () {
            this.status = TASK_DROP;
            return this
        }, execute: function () {
            if (+new Date - this.lastExecTime < this.gap) {
                return false
            }
            this.fn();
            this.lastExecTime = +new Date;
            return true
        }, getGap: function () {
            return this.gap
        }, setGap: function (newGap) {
            this.gap = newGap;
            return this
        }, isRunning: function () {
            return this.status === TASK_RUN
        }, isPaused: function () {
            return this.status === TASK_PAUSE
        }, isDropped: function () {
            return this.status === TASK_DROP
        }
    };
    return new TM
});
BizQQWPA.define("lang.browser", function () {
    var ua = navigator.userAgent.toLowerCase();
    var browser = {};
    var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || /(webkit)[ \/]([\w.]+)/.exec(ua) || /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || /(msie) ([\w.]+)/.exec(ua) || ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || [];
    var matchIe11;
    if (ua.indexOf("trident") > -1 && (matchIe11 = /rv:([\d.]+)/.exec(ua))) {
        match[1] = "msie";
        match[2] = matchIe11[1]
    }
    var matched = {browser: match[1] || "", version: match[2] || "0"};
    if (matched.browser) {
        browser[matched.browser] = true;
        browser.version = matched.version
    }
    if (browser.chrome) {
        browser.webkit = true
    } else if (browser.webkit) {
        browser.safari = true
    }
    var isMobile = browser.isMobile = ua.match(/(nokia|iphone|android|motorola|^mot\-|softbank|foma|docomo|kddi|up\.browser|up\.link|htc|dopod|blazer|netfront|helio|hosin|huawei|novarra|CoolPad|webos|techfaith|palmsource|blackberry|alcatel|amoi|ktouch|nexian|samsung|^sam\-|s[cg]h|^lge|ericsson|philips|sagem|wellcom|bunjalloo|maui|symbian|smartphone|midp|wap|phone|windows ce|iemobile|^spice|^bird|^zte\-|longcos|pantech|gionee|^sie\-|portalmmm|jig\s browser|hiptop|^ucweb|^benq|haier|^lct|opera\s*mobi|opera\*mini|320x320|240x320|176x220)/i);
    browser.isWindow = /windows|win32/.test(ua);
    browser.isMac = /Mac/.test(ua);
    browser.isIOS = /(?:iphone|ipad|ipod)/i.test(ua);
    browser.isAndroid = /android/i.test(ua);
    if (isMobile) {
        var QQReg = /QQ\/(\d+\.\d+)\.\d/, OldQQReg = /V1_AND_SQ_(\d+\.\d+)\.\d/, match = QQReg.exec(ua) || OldQQReg.exec(ua);
        browser.isQQ = !match;
        match && (browser.QQVersion = match[1])
    }
    return browser
});
BizQQWPA.define("util.pad", function () {
    return function (str, pad, length, isLeft) {
        var padLength = length - str.length, i;
        if (isLeft === false) {
            for (i = 0; i < padLength; i++) {
                str += pad
            }
        } else {
            for (i = 0; i < padLength; i++) {
                str = pad + str
            }
        }
        return str
    }
});
BizQQWPA.define("util.Bits", "util.proxy,util.pad", function (require) {
    var proxy = require("proxy"), pad = require("pad");
    return function () {
        var setChar = function (str, index, newChar) {
            return str.replace(new RegExp("(^[\\d]{" + index + "})\\d"), "$1#" + newChar).replace("#", "")
        };
        var Bits = function (bits) {
            this.bits = bits
        };
        Bits.prototype = {
            pad: function () {
                var args = Array.prototype.slice.call(arguments);
                this.bits = pad.apply(this, [this.bits].concat(args));
                return this
            }, padLeft: function () {
                return proxy(this, this.pad)
            }, padRight: function () {
                var args = Array.prototype.slice.call(arguments).push(false);
                return this.pad.apply(this, args)
            }, getChar: function (index) {
                return this.bits.charAt(index)
            }, setChar: function (index, value) {
                this.bits = setChar(this.bits, index, value);
                return this
            }, reverse: function () {
                var bits = this.bits, length = bits.length;
                for (var i = 0; i < length; i++) {
                    this.setChar(i, parseInt(bits[i], 2) ^ 1)
                }
                return this
            }
        };
        return Bits
    }()
});
BizQQWPA.define("util.events", function () {
    var events = {};
    events.addEvent = window.addEventListener ? function (node, type, event) {
        node.addEventListener(type, event);
        return node
    } : function (node, type, event) {
        node.attachEvent("on" + type, event);
        return node
    };
    events.removeEvent = window.removeEventListener ? function (node, type, event) {
        node.removeEventListener(type, event);
        return node
    } : function (node, type, event) {
        node.detachEvent("on" + type, event);
        return node
    };
    return events
});
BizQQWPA.define("util.onLoad", "util.events", function (require) {
    var events = require("events");
    return onLoad = function (fn, context) {
        context = context || window;
        if (/loaded|complete|undefined/.test(context.document.readyState)) {
            fn()
        } else {
            events.addEvent(context, "load", fn)
        }
        return context
    }
});
BizQQWPA.define("util.offset", function () {
    var doc = document, isStandardMode = doc.compatMode == "CSS1Compat", docElem = doc.documentElement, body = doc.body;
    return {
        getScrollTop: function () {
            return Math.max(docElem.scrollTop, body.scrollTop)
        }, getClientWidth: function () {
            return isStandardMode ? docElem.clientWidth : body.clientWidth
        }, getClientHeight: function () {
            return isStandardMode ? docElem.clientHeight : body.clientHeight
        }
    }
});
BizQQWPA.define("util.Panel", "lang.browser,util.Style,util.className,util.events,util.offset,util.css,util.proxy", function (require) {
    var Style = require("Style"), className = require("className"), events = require("events"), offset = require("offset"), browser = require("browser"), css = require("css"), proxy = require("proxy");
    var SETTINGS = {
        container: document.getElementsByTagName("body")[0],
        template: ['<div class="WPA3-CONFIRM">', '<h3 class="WPA3-CONFIRM-TITLE"><%=title%></h3>', '<div class="WPA3-CONFIRM-CONTENT"><%=content%></div>', '<div class="WPA3-CONFIRM-PANEL"><%=buttons%></div>', '<div class="WPA3-CONFIRM-CLOSE"></div>', "</div>"].join(""),
        buttonTemplate: ['<a href="javascript:;" class="WPA3-CONFIRM-BUTTON"><span class="WPA3-CONFIRM-BUTTON-PADDING WPA3-CONFIRM-BUTTON-LEFT"></span><span class="WPA3-CONFIRM-BUTTON-TEXT"><%=text%></span><span class="WPA3-CONFIRM-BUTTON-PADDING WPA3-CONFIRM-BUTTON-RIGHT"></span></a>'].join(""),
        cssText: [".WPA3-CONFIRM { z-index:2147483647; width:285px; height:141px; margin:0; background:url() no-repeat;}", ".WPA3-CONFIRM { *background-image:url(http://combo.b.qq.com/crm/wpa/release/3.3/wpa/views/panel.png);}", '.WPA3-CONFIRM * { position:static; z-index:auto; top:auto; left:auto; right:auto; bottom:auto; width:auto; height:auto; max-height:auto; max-width:auto; min-height:0; min-width:0; margin:0; padding:0; border:0; clear:none; clip:auto; background:transparent; color:#333; cursor:auto; direction:ltr; filter:; float:none; font:normal normal normal 12px "Helvetica Neue", Arial, sans-serif; line-height:16px; letter-spacing:normal; list-style:none; marks:none; overflow:visible; page:auto; quotes:none; -o-set-link-source:none; size:auto; text-align:left; text-decoration:none; text-indent:0; text-overflow:clip; text-shadow:none; text-transform:none; vertical-align:baseline; visibility:visible; white-space:normal; word-spacing:normal; word-wrap:normal; -webkit-box-shadow:none; -moz-box-shadow:none; -ms-box-shadow:none; -o-box-shadow:none; box-shadow:none; -webkit-border-radius:0; -moz-border-radius:0; -ms-border-radius:0; -o-border-radius:0; border-radius:0; -webkit-opacity:1; -moz-opacity:1; -ms-opacity:1; -o-opacity:1; opacity:1; -webkit-outline:0; -moz-outline:0; -ms-outline:0; -o-outline:0; outline:0; -webkit-text-size-adjust:none;}', ".WPA3-CONFIRM * { font-family:Microsoft YaHei,Simsun;}", ".WPA3-CONFIRM .WPA3-CONFIRM-TITLE { height:40px; margin:0; padding:0; line-height:40px; color:#2b6089; font-weight:normal; font-size:14px; text-indent:80px;}", ".WPA3-CONFIRM .WPA3-CONFIRM-CONTENT { height:55px; margin:0; line-height:55px; color:#353535; font-size:14px; text-indent:29px;}", ".WPA3-CONFIRM .WPA3-CONFIRM-PANEL { height:30px; margin:0; padding-right:16px; text-align:right;}", ".WPA3-CONFIRM .WPA3-CONFIRM-BUTTON { position:relative; display:inline-block!important; display:inline; zoom:1; width:99px; height:30px; margin-left:10px; line-height:30px; color:#000; text-decoration:none; font-size:12px; text-align:center;}", ".WPA3-CONFIRM .WPA3-CONFIRM-BUTTON-FOCUS { width:78px;}", ".WPA3-CONFIRM .WPA3-CONFIRM-BUTTON .WPA3-CONFIRM-BUTTON-TEXT { line-height:30px; text-align:center; cursor:pointer;}", ".WPA3-CONFIRM-CLOSE { position:absolute; top:7px; right:7px; width:10px; height:10px; cursor:pointer;}"].join(""),
        buttons: [{
            isFocus: true, text: "确认", events: {
                click: function () {
                    this.remove()
                }
            }
        }, {
            text: "取消", events: {
                click: function () {
                    this.remove()
                }
            }
        }],
        modal: true
    };
    Style.add("_WPA_CONFIRM_STYLE", SETTINGS.cssText);
    var Panel = function (opts) {
        this.opts = opts;
        this.render()
    };
    Panel.prototype = {
        render: function () {
            var panel = this, opts = this.opts, body = this.container = opts.container || document.getElementsByTagName("body")[0];
            var frameHTML = opts.template || SETTINGS.template, buttonReplaceID = "WPA_BUTTONS_PLACE" + +new Date % 100 + Math.floor(Math.random() * 100);
            frameHTML = frameHTML.replace(/<%=title%>/g, opts.title || "").replace(/<%=content%>/g, opts.content || "").replace(/<%=buttons%>/g, '<div id="' + buttonReplaceID + '"></div>');
            var frag = document.createElement("div"), frame;
            frag.innerHTML = frameHTML;
            this.$el = frame = frag.firstChild;
            events.addEvent(frame.lastChild, "click", function () {
                panel.remove();
                opts.onClose && opts.onClose()
            });
            (function () {
                try {
                    body.appendChild(frame)
                } catch (e) {
                    setTimeout(arguments.callee, 1);
                    return
                }
                if (opts.modal || SETTINGS.modal) {
                    panel.renderModal()
                }
                panel.renderButtons(buttonReplaceID);
                panel.setCenter()
            })()
        }, renderButtons: function (buttonReplaceID) {
            var replaceElement = document.getElementById(buttonReplaceID), parentNode = replaceElement.parentNode;
            parentNode.removeChild(replaceElement);
            var buttonOpts = this.opts.buttons || SETTINGS.buttons, buttonTempl = this.opts.buttonTemplate || SETTINGS.buttonTemplate, frag = document.createElement("div"), button, opt, evts;
            for (var i = 0, l = buttonOpts.length; i < l; i++) {
                opt = buttonOpts[i];
                frag.innerHTML = buttonTempl.replace("<%=text%>", opt.text);
                button = frag.firstChild;
                opt.isFocus && className.addClass(button, "WPA3-CONFIRM-BUTTON-FOCUS");
                if (opt.events) {
                    evts = opt.events;
                    for (var type in evts) {
                        if (evts.hasOwnProperty(type)) {
                            events.addEvent(button, type, proxy(this, evts[type]))
                        }
                    }
                }
                parentNode.appendChild(button)
            }
        }, renderModal: function () {
            var container = this.container, width = css(container, "width"), height = css(container, "height"), overflow = css(container, "overflow");
            var modalLayer = document.createElement("div"), styles = {
                position: "fixed",
                top: 0,
                left: 0,
                zIndex: 2147483647,
                width: offset.getClientWidth() + "px",
                height: offset.getClientHeight() + "px",
                backgroundColor: "black",
                opacity: .3,
                filter: "alpha(opacity=30)"
            };
            var isQuirk = document.compatMode === "BackCompat";
            if (browser.msie && parseInt(browser.version, 10) < 7 || isQuirk) {
                styles.position = "absolute";
                setInterval(proxy(modalLayer, function () {
                    this.style.top = offset.getScrollTop() + "px"
                }), 128)
            }
            css(modalLayer, styles);
            container.insertBefore(modalLayer, this.$el);
            this.modal = modalLayer;
            events.addEvent(window, "resize", proxy(modalLayer, function () {
                css(this, {width: offset.getClientWidth() + "px", height: offset.getClientHeight() + "px"})
            }))
        }, show: function () {
            this.css("display", "block");
            this.modal && css(this.modal, "display", "block");
            return this
        }, hide: function () {
            this.css("display", "none");
            this.modal && css(this.modal, "display", "none");
            return this
        }, remove: function () {
            this.$el.parentNode.removeChild(this.$el);
            this.modal && this.modal.parentNode.removeChild(this.modal);
            return this
        }, css: function () {
            var args = [this.$el].concat(Array.prototype.slice.call(arguments));
            return css.apply(this, args)
        }, setCenter: function () {
            this.css({position: "absolute", top: "50%", left: "50%"});
            var styles = {
                position: "fixed",
                marginLeft: "-" + this.outerWidth() / 2 + "px",
                marginTop: "-" + this.outerHeight() / 2 + "px"
            };
            var isQuirk = document.compatMode === "BackCompat";
            if (browser.msie && parseInt(browser.version, 10) < 7 || isQuirk) {
                styles.position = "absolute";
                styles.marginTop = 0;
                var top = styles.top = (offset.getClientHeight() - this.outerHeight()) / 2;
                setInterval(proxy(this.$el, function () {
                    this.style.top = offset.getScrollTop() + top + "px"
                }), 128)
            }
            this.css(styles)
        }, outerWidth: function () {
            return this.$el.offsetWidth
        }, outerHeight: function () {
            return this.$el.offsetHeight
        }
    };
    return Panel
});